package com.fw.basesystem;

public class BaseSystemDemo {

    public static void main(String[] args) {
        // 从右到左，从上至下去计算
        // 二进制 0b 打头
         int a = 0b1110111; // 119
        int a1 = 0b1111010; // 122
    int result = 0b0001101; // -3
        int a2 = 0b1101;   // 13
        int a3 = 0b1101010;// 106
        int a4 = 0b1110111; // 119


        // 八进制 0打头
        int b =  01765;
        int b1 = 043211;

        // 十六进制 0x 打头
        int c =  0x1fffa;
        int c1 = 0x2ffab;


        // 二进制转化  转化10 进制
        int f1 = 0B10010110;
        //0B10010110 从右到左，系数乘基数 次方 权
        //0 * （2^0） + 1 * （2^1） + 1 * （2^2）+ 0 * （2^3） + 1 * （2^4） + 0 * （2^5） + 0 * （2^6） + 1 * （2^7）
        // 0 + 2 + 4 + 0 + 16 + 0 + 0 + 128  = 150

        //System.out.println(f1);

        //BCD 码 快速转换规律 思路转化一下 从左到右
        /**
         * 二进制到八进制 3位组合
         * 二进制到十六进制 4位组合
         */
        int p1 = 0xef9; // e = 15 , f = 14
        // 二进制为   1001 1111 1101
        // 十进制为   9 * (16 ^ 0) +  15 * (16 ^ 1) +  14 * (16 ^ 2) = 3833 || 1001( 2048 + 256), 1111(240), 1101(13)
        // 八进制为   100  111 111 101 = 4 + 7 + 7 + 5 = 2557
         int p2 = 04775;

         // 按照 BCD 方式如果多的话就 前边放一位单独算，少的话，就补一位0 https://zhidao.baidu.com/question/96058483.html
         int p3 = 1728;
        // 1024   512   128 64
         // 二进制 =>  1101 1000 000
        // 16 进制 =>  0110 1100 0000 => 0x6c0
        // 8 进制 =>   011 011 000 000 => 3300
        System.out.println(Integer.toBinaryString(p3));




        //System.out.println( 10 | 2);


        // 八进制 转二进制，十进制，十六进制
        int o1 = 07612;
        //
        // 二进制 1(2048)  1(1024)  1(512)  1(256)  1(128)  0(64)   0(32)   0(16) 1(8) 0(4) 1(2)    0(1)
        // 十进制  2 + 8 + 128 + 256 + 512 + 1024 +  2048 = 3978
        // 十六进制 1111 1000 1010 = 0Xf8a


        // 16 进制 转 二进制，八进制，十进制
        int o2 = 0x0fa3;  //1111 1010 0011
        // 二进制 （0000,遇 0 忽略） 1111 1010 0011
        // 十进制  3 + 32 + 128 + 256 + 512 + 1024 + 2048 = 4003
        // 八进制  111 110 100 011 =  7643

        // 2 进制 转 10 进制 ， 八进制，16进制
        int o3 = 0b10100101;
        // 十进制 = 1 + 4 + 32  + 128 = 165
        // 八进制 = 010 100 101 = 245
        // 16 进制 =  1010 0101 = a5

        // 二进制
        int o4 = 0b101001;
        // 十进制 = 1 + 8 + 32 = 41
        // 16进制= 0010  1001 =29
        // 8 进制= 101 001  = 51

        // 二进制
        int o5 = 0b1010010;
        // 十进制 = 2 + 16 + 64 = 82
        // 16进制= 0101  0010 =  52
        // 8 进制= 001 010 010  = 122

       // System.out.println(7 == 0b111);


        // 正反补。
        /**
         * 什么是原码
         * 就是二进制定点表示法，即最高位为符号位，“0”表示正，“1”表示负，其余位表示数值的大小。
         * 什么是反码
         * 正数的反码与其原码相同，负数的反码是对其原码逐位取反，但符号位除外。
         * 什么是补码
         * 正数的补码与其原码相同，负数的补码是在其反码的末位加1。
         */
        // 正数
        int l1 = 18;
        // 正数 正反补都一样  表示起来就是 0 0000000 00000000 00000000 00010010

        int l2 = -18;
        // 负数不大一样,按照说明原则.
        // 原码：1 0000000 00000000 00000000 00010010
        // 反码：1 1111111 11111111 11111111 11101101
        // 补码：1 1111111 11111111 11111111 11101110 （末位加1）
        // (比较典型的例子) 末位已经是1 了  末位加1 末位加1 末位加1 特记
        System.out.println(0b11111111111111111111111111101110);
        // 补码反推到原码
        //补码：1 1111111 11111111 11111111 11101110
        //反码：1 0000000 00000000 00000000 00010010
        //原码: 1 0000000 00000000 00000000 00010010
        System.out.println(Integer.toBinaryString(-88));
        //-88
        // 原码 1 0000000  00000000 00000000 01011000
        // 反码 1 1111111  11111111 11111111 10100111
        // 补码 1 1111111  11111111 11111111 10101000 // 加一位

       // 按位与 如果当前位两个二进制，两个相同则为1否则为0

        int k1  = 8 & 9;
        // 二进制
        // 8： 00000000 00000000 00000000 00001000
        // 9： 00000000 00000000 00000000 00001001
        // 结果 00000000 00000000 00000000 00001000 = 8
        System.out.println(k1);

        // 按位或 二进制中，如果当前位两个二进制 相同一个则为1否则为0
        int k2 = 19 | 13;
        // 二进制:
        // 19:  00000000 00000000 00000000 00100011
        // 13:  00000000 00000000 00000000 00010001
        //结果:  00000000 00000000 00000000 00110011 = 31
        System.out.println(k2);

        // 按位异或 当前位的两个二进制表示不同则为1相同则为0
        int k3 = 10^13;
        // 二进制:
        // 10: 00000000 00000000 00000000 00001010
        // 13: 00000000 00000000 00000000 00001101
        //结果: 00000000 00000000 00000000 00000111 = 7
        System.out.println(k3);

        // ~取反 二进制位
        int m1 = ~6;
        // 二进制位 : 00000000 00000000 00000000 00000111
        // 取反:     11111111 11111111 11111111 11111000
        System.out.println(m1);
        // << 左移 （操作数乘（2的n次幂））n 就是位数 （放大倍数）
        // 例如 int k4 = 8 << 2   (8*(2^2)) = 32
        int k4 = 8 << 2;
        // 二进制
        //   8:      00000000 00000000 00000000 00001000
        //左移(去掉最高位的两位,后补0):
        //           00000000 00000000 00000000 00100000
        System.out.println(k4);
        // 在举一个例子，负数
        k4 = -8 << 2;
        // 二进制:
        //原码： 1 0000000 00000000 00000000 00001000
        //反码： 1 1111111 11111111 11111111 11110111
        //补码： 1 1111111 11111111 11111111 11111000 +1
        // 左移 2 位:（忽视高位，移动2位后，补0）
        //      1 1111111 11111111 11111111 11100000
        // 反码：1 0000000 00000000 00000000 00011111 -1 = 32
        // 补码：1 0000000 00000000 00000000 00100000
        System.out.println(k4);
        // 11011

       //  >> 右移 （操作数/(2^n)） 右移的时候，
        // 填充的数据以最高位那个数为准，如果是1 填充1，如果是0填充1，和左移完全不一样，左移填充的都是0;
        int n1 = 8>>2;
        // 二进制:
        //     00000000 00000000 00000000 00001000
        //结果：00000000 00000000 00000000 00000010 = 2
        System.out.println(n1);
        int n2 = -8 >>2;
        // 二进制
        //  原码:   10000000 00000000 00000000 00001000
        //  反码:   11111111 11111111 11111111 11110111
        //  补码:   11111111 11111111 11111111 11111000 +1
        // 右移动2位，填充以符号位为准
        //          11111111 11111111 11111111 11111110
        //    反码： 10000000 00000000 00000000 00000001
        //    补码:  10000000 00000000 00000000 00000010 -1 是负数，所以还是按照进码的方式
        System.out.println(n2);

        int n3 = 9 >>2;
        // 二进制
        // 00000000 00000000 00000000 00001001
        // 右移2位 拿高位补
        // 0000000000 00000000 00000000 000010 = 2
        System.out.println(n3);

       // 无符号右移 ,无符号最大的区别就是负数 右移的时候不在拿最高位补而是补0.
        int z1 = -36 >>> 3; //= 536870907
        //  - 36:
        //       1 0000000 00000000 00000000 00100100
        //反码：  1 1111111 11111111 11111111 11011011
        //补码:   1 1111111 11111111 11111111 11011100 +1
        // 右移动3位 用0 补齐
       //        0 0011111 11111111 11111111 11111011
        // 高位换0 无需反码操作，因为直接就是 补码:   0 0011111 11111111 11111111 11111011  = 536870907
        System.out.println(z1);




    }
}
